1. Field of the Invention
The invention relates generally to operating system environments, and more particularly, to systems and methods for providing alternate operating environments within a single native operating environment.
2. Description of the Related Art
For a host operating system to execute an application written for a different operating system, the host operating system must provide the foreign application with the services and environment the foreign application expects. Providing these expected services and environment to a foreign application is complicated. Counter intuitively, providing services and environment to a foreign application is most complicated when the host operating system and the operating system for which the foreign application was written have substantial similarities. Such similarities can cause collisions in the placement and/or naming of resources. These collisions can include undesirable overlap in system libraries, configuration files, and network ports, etc. of the respective operating systems and, in most cases, the overlap is fatal. For example, the Linux™ and Solaris™ operating systems use the same file “/etc/passwd” to store the list of users and corresponding passwords of every user on a system. However, the format of the “/etc/passwd” file in the Linux™ operating system is different from the format of the “/etc/passwd” file in the Solaris™ operating system. Therefore, when a Linux™-based application executing in a Solaris™ environment attempts to validate a particular user, the Linux™-based application fails because the application does not know how to process the format of the data contained in the Solaris™ “/etc/passwd” file.
Conventionally, one solution for allowing a host operating system to execute an application written for a different operating system and avoiding collisions like those discussed above involves file system namespace partitioning. File system namespace partitioning provides a separation between host (native) and foreign (non-native) operating system environments. Two general approaches are normally used to perform file system namespace partitioning, namely the “chroot” (change root) operation and path mapping mechanisms. Change root (“chroot”) is a standard UNIX™ etc. operation for restricting a process' view of a full file system to a limited sub-tree within the file system. For example, the “chroot” operation can set the “root directory” of a restricted process to a given path that is located at a subdirectory (e.g. “/compat”) below a real root directory (“/”) which is located at the top-most directory in the hierarchy of the underlying file system, as illustrated in Table A below:
TABLE A
By designating a node within the host file system hierarchy to be the “root” node visible to the restricted process (e.g. “/compat” in Table A), all path translations are performed relative to the new root node. This approach has been used to prevent a foreign application running in a host environment from accidentally referring to the files belonging to the native operating system. However, there is frequently collision-free data located within the host's file system hierarchy that a restricted process may want or need to access. And since this data exists outside the limited universe created by “chroot,” the restricted process will not have access to the data located in host's file system hierarchy.
Path mapping is a more complex approach to solving the collision problems caused by similarities between the operating system for which a foreign application was written and the native operating system hosting the foreign application. Unlike “chroot,” which causes all path translations to be defined relative to a new root node, path mapping affects only a subset of all translations. In other words, path mapping allows an operating system to remap requests for operating system files (e.g., libraries, configuration files, etc.) while allowing requests for user data files to be passed through to the native operating system kernel without modification.
Typically, in path mapping, collisions between the foreign operating system and the host operating system are identified in advance, and a directory (within the host file system) is provided that includes any directories and/or files associated with the foreign operating system that conflict with corresponding files or directories of the host operating system. During execution of the foreign application, the host operating system intercepts references made by the foreign application to a conflicting directory or file, and transparently remaps the reference to a corresponding directory or file in the directory of conflicting foreign directories and/or files. For example, if a Linux™ application executing on a Solaris™ operating system tried to open the file “/etc/passwd,” the open call would be intercepted and “/etc/passwd” would be transparently remapped to “/compat/Linux/etc/passwd.” Unfortunately, the path mapping approach discussed above does not work efficiently when entire directories are being remapped. The path mapping approach is also fragile. More particularly, the path mapping approach requires a host operating system to know in advance which files and directories will need to be remapped. The slightest change in the file naming used by the foreign operating system can completely break the path mapping mechanism. Another complication is that operating systems (e.g. UNIX™, Solaris™, etc.) usually maintain a notion of where a process is (i.e. its current location within a host file namespace hierarchy) so that when a command like “pwd” (print working directory) is used, what is returned is an exact location of the process is with respect to the file system namespace hierarchy. And if a process changes directory (“cd”) to “/foo” and the “/foo” directory has been remapped to “/compat/Linux/foo” everything is fine. However, if a process then calls “pwd” after changing the directory to “/foo” the process expects to get back “/foo.” Unfortunately, the process is actually in the “/compat/Linux/foo” directory and “/compat/Linux/foo” will be returned from the “pwd” call unless a reverse mapping transparently carried out from “/compat/Linux/foo” back to “/foo.” A significant amount of overhead is required to perform this type of mapping and reverse mapping. Moreover, the path mapping approach becomes untenably complicated when mixing the usage of native and foreign applications. Since native and foreign applications have different views of the host file system and their places within it, they cannot sensibly communicate about file-related data. For example, it is difficult for a native web browser to invoke a foreign utility to display a data file. Path mapping and “chroot ( )” techniques are also both limited to virtualizing the file system namespace. The primary focus of both techniques is on preventing foreign processes from accidentally accessing native files.
Another solution for allowing a host operating system to execute an application written for a different operating system involves “full system virtualization.” Full system virtualization provides a capability to execute a complete instance of an operating system within a virtual machine on top of a different operating system. For example, VMware™, Xen™, VirtualPC™, and Parallels™ all provide full system virtualization. Parallels™ provides a capability for executing Solaris applications on top of MacOS X™ operating systems, VMWare™ provides a capability for executing Windows™ applications on top of Linux™ operating systems, and so on. Full system virtualization involves virtualization at the hardware level of a computer system. Therefore, the operating systems being virtualized must be fully installed on the host computer system, including the operating system's kernel. This full-system approach requires hundreds of megabytes of memory to accommodate the virtualized operating system as well as approximately one megabyte of memory for each corresponding application. Moreover, because of such considerable resource requirements, only a few applications can be executed.
In view of the forgoing, there is a need to separate the environments of native and foreign operating systems in a manner that allows interoperability while avoiding resource collisions and unnecessary overhead.